package net.entelijan.cobean.notification;

import static org.junit.Assert.assertEquals;

import java.util.List;

import net.entelijan.cobean.core.ColumnDesc;
import net.entelijan.cobean.core.ISingleSelectionListCobean;
import net.entelijan.cobean.core.impl.IPropertyChangeListenerAware;
import net.entelijan.cobean.table.DefaultSingleSelectionTableInitializer;
import net.entelijan.testutil.CobeanTestUtil;
import net.entelijan.testutil.SimpleBean;

import org.fest.swing.fixture.FrameFixture;
import org.fest.swing.fixture.JTableFixture;
import org.fest.swing.fixture.JTextComponentFixture;
import org.junit.Test;

public class SingleSelectionTableNotificationFestTestCase {

	/**
	 * Tests the setting of values, and deselection selection of rows from the
	 * GUI and deselection from GUI
	 */
	@Test
	public void testSelectDeselectFromGUI() {
		TableNotificationTestFrame frame = new TableNotificationTestFrame("TF");
		FrameFixture frameFix = new FrameFixture(frame);
		try {
			frameFix.show();
			JTableFixture tableFix = frameFix.table("table");

			// Create to property change listeners for recording the events.
			final RecordingPropertyChangeListener valueListener = new RecordingPropertyChangeListener(
					"value");
			final RecordingPropertyChangeListener selListener = new RecordingPropertyChangeListener(
					"selectedValue");

			// Create the cobean
			ISingleSelectionListCobean<SimpleBean> cobean = createCobean(frame);

			// Add the listeners to the cobean
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(valueListener);
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(selListener);

			// Set a list of Simple beans to the cobean
			{
				List<SimpleBean> value = CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer");
				cobean.setValue(value);
				// Assert that the value listener was notified exactly ones
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());
				assertEventContentBean(null, CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer"),
						"value", valueListener.getEventContents().get(0));
			}

			// Select one row from the GUI
			{
				tableFix.selectCell(tableFix.cell("Zauberer"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());
				assertEventContentBean(null, new SimpleBean("Zauberer"),
						"selectedValue", selListener.getEventContents().get(0));

			}

			// Select another row
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
			}

			// Select the same row and ensure that no events where fired
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
			}

			// Select the same row again and ensure that no events where fired
			{
				cobean.setSelectedValue(new SimpleBean("der"));
				pause();
				assertEquals("der", tableFix.selectionValue());
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
			}

			// Select another row
			{
				cobean.setSelectedValue(new SimpleBean("Assistent"));
				pause();
				assertEquals("Assistent", tableFix.selectionValue());
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(3, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("der"), new SimpleBean(
						"Assistent"), "selectedValue", selListener
						.getEventContents().get(2));
			}

			// Deselect all rows and ensure that an event is fired
			cobean.setSelectedValue(null);
			pause();
			assertEquals(null, tableFix.selectionValue());
			assertEquals(1, valueListener.getNotificationCount());
			assertEquals(4, selListener.getNotificationCount());
			assertEventContentBean(new SimpleBean("Assistent"), null,
					"selectedValue", selListener.getEventContents().get(3));

		} finally {
			frameFix.cleanUp();
		}

	}

	/**
	 * Tests the setting of values, and deselection selection of rows from the
	 * GUI and deselection from GUI with sorting.
	 */
	@Test
	public void testSelectDeselectSortingFromGUI() {
		TableNotificationTestFrame frame = new TableNotificationTestFrame("TF");
		FrameFixture frameFix = new FrameFixture(frame);
		try {
			frameFix.show();
			JTableFixture tableFix = frameFix.table("table");

			// Create to property change listeners for recording the events.
			final RecordingPropertyChangeListener valueListener = new RecordingPropertyChangeListener(
					"value");
			final RecordingPropertyChangeListener selListener = new RecordingPropertyChangeListener(
					"selectedValue");

			// Create the cobean
			ISingleSelectionListCobean<SimpleBean> cobean = createCobean(frame);

			// Add the listeners to the cobean
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(valueListener);
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(selListener);

			// Set a list of Simple beans to the cobean
			{
				List<SimpleBean> value = CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer");
				cobean.setValue(value);

				// Assert that the value listener was notified exactly ones
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());
				assertEventContentBean(null, CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer"),
						"value", valueListener.getEventContents().get(0));

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}

			// Sort the list. No Event should be thrown.
			{
				tableFix.tableHeader().clickColumn(0);
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}
			// Select one row from the GUI
			{
				tableFix.selectCell(tableFix.cell("Zauberer"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());
				assertEventContentBean(null, new SimpleBean("Zauberer"),
						"selectedValue", selListener.getEventContents().get(0));
				// Check if the right bean is selected.
				assertEquals("Zauberer", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select another row from the GUI
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select the same row from the GUI
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
		} finally {
			frameFix.cleanUp();
		}

	}

	/**
	 * Tests the setting of values, and deselection selection of rows from the
	 * GUI and deselection from GUI with sorting.
	 */
	@Test
	public void testSelectDeselectFilteringFromGUI01() {
		TableNotificationTestFrame frame = new TableNotificationTestFrame("TF");
		FrameFixture frameFix = new FrameFixture(frame);
		try {
			frameFix.show();
			JTableFixture tableFix = frameFix.table("table");
			JTextComponentFixture filterFix = frameFix.textBox("filterTextField");

			// Create to property change listeners for recording the events.
			final RecordingPropertyChangeListener valueListener = new RecordingPropertyChangeListener(
					"value");
			final RecordingPropertyChangeListener selListener = new RecordingPropertyChangeListener(
					"selectedValue");

			// Create the cobean
			ISingleSelectionListCobean<SimpleBean> cobean = createCobean(frame);

			// Add the listeners to the cobean
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(valueListener);
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(selListener);

			// Set a list of Simple beans to the cobean
			{
				List<SimpleBean> value = CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer");
				cobean.setValue(value);

				// Assert that the value listener was notified exactly ones
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());
				assertEventContentBean(null, CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer"),
						"value", valueListener.getEventContents().get(0));

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}

			// filter the list. No Event should be thrown.
			{
				filterFix.enterText("r");
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}
			// Select one row from the GUI
			{
				tableFix.selectCell(tableFix.cell("Zauberer"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());
				assertEventContentBean(null, new SimpleBean("Zauberer"),
						"selectedValue", selListener.getEventContents().get(0));
				// Check if the right bean is selected.
				assertEquals("Zauberer", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select another row from the GUI
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select the same row from the GUI
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
		} finally {
			frameFix.cleanUp();
		}

	}

	/**
	 * Tests the setting of values, and deselection selection of rows from the
	 * GUI and deselection from GUI with sorting.
	 * Filter after selection that the selected value is no longer shown.
	 */
	@Test
	public void testSelectDeselectFilteringFromGUI02() {
		TableNotificationTestFrame frame = new TableNotificationTestFrame("TF");
		FrameFixture frameFix = new FrameFixture(frame);
		try {
			frameFix.show();
			JTableFixture tableFix = frameFix.table("table");
			JTextComponentFixture filterFix = frameFix.textBox("filterTextField");

			// Create to property change listeners for recording the events.
			final RecordingPropertyChangeListener valueListener = new RecordingPropertyChangeListener(
					"value");
			final RecordingPropertyChangeListener selListener = new RecordingPropertyChangeListener(
					"selectedValue");

			// Create the cobean
			ISingleSelectionListCobean<SimpleBean> cobean = createCobean(frame);

			// Add the listeners to the cobean
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(valueListener);
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(selListener);

			// Set a list of Simple beans to the cobean
			{
				List<SimpleBean> value = CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer");
				cobean.setValue(value);

				// Assert that the value listener was notified exactly ones
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());
				assertEventContentBean(null, CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer"),
						"value", valueListener.getEventContents().get(0));

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}

			// Select one row from the GUI
			{
				tableFix.selectCell(tableFix.cell("Zauberer"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());
				assertEventContentBean(null, new SimpleBean("Zauberer"),
						"selectedValue", selListener.getEventContents().get(0));
				// Check if the right bean is selected.
				assertEquals("Zauberer", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// filter the list in a way that the slected value is no longer shown. 
			// No Event should be thrown.
			{
				filterFix.enterText("A");
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
				
				assertEquals("Zauberer", cobean.getSelectedValue().getStrVal());
			}
			
			// clear the filter. 
			// No Event should be thrown.
			{
				filterFix.deleteText();
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
				
				assertEquals("Zauberer", cobean.getSelectedValue().getStrVal());
			}
			
			
			// Select another row from the GUI
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select the same row from the GUI
			{
				tableFix.selectCell(tableFix.cell("der"));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
		} finally {
			frameFix.cleanUp();
		}

	}

	/**
	 * Tests the setting of values, and deselection selection of rows from the
	 * cobean and deselection from cobean with sorting.
	 */
	@Test
	public void testSelectDeselectSortingFromCobean() {
		TableNotificationTestFrame frame = new TableNotificationTestFrame("TF");
		FrameFixture frameFix = new FrameFixture(frame);
		try {
			frameFix.show();
			JTableFixture tableFix = frameFix.table("table");

			// Create to property change listeners for recording the events.
			final RecordingPropertyChangeListener valueListener = new RecordingPropertyChangeListener(
					"value");
			final RecordingPropertyChangeListener selListener = new RecordingPropertyChangeListener(
					"selectedValue");

			List<SimpleBean> value = CobeanTestUtil
					.createSimpleBeanList("Der Assistent der Zauberer");

			// Create the cobean
			ISingleSelectionListCobean<SimpleBean> cobean = createCobean(frame);

			// Add the listeners to the cobean
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(valueListener);
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(selListener);

			// Set a list of Simple beans to the cobean
			{
				cobean.setValue(value);

				// Assert that the value listener was notified exactly ones
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());
				assertEventContentBean(null, CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer"),
						"value", valueListener.getEventContents().get(0));

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}

			// Sort the list. No Event should be thrown.
			{
				tableFix.tableHeader().clickColumn(0);
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}
			// Sort again the list. No Event should be thrown.
			{
				tableFix.tableHeader().clickColumn(0);
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());
			}
			// Select one row from the cobean
			{
				cobean.setSelectedValue(value.get(3));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());
				assertEventContentBean(null, new SimpleBean("Zauberer"),
						"selectedValue", selListener.getEventContents().get(0));
				// Check if the right bean is selected.
				assertEquals("Zauberer", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select another row from the cobean
			{
				cobean.setSelectedValue(value.get(2));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"), new SimpleBean(
						"der"), "selectedValue", selListener
						.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}
			// Select the same row from the cobean
			{
				cobean.setSelectedValue(value.get(2));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"), new SimpleBean(
						"der"), "selectedValue", selListener
						.getEventContents().get(1));
				// Check if the right bean is selected.
				assertEquals("der", cobean.getSelectedValue().getStrVal());

				// Check the order of the list has not changed
				assertEquals("Der", cobean.getValue().get(0).getStrVal());
				assertEquals("Assistent", cobean.getValue().get(1).getStrVal());
				assertEquals("der", cobean.getValue().get(2).getStrVal());
				assertEquals("Zauberer", cobean.getValue().get(3).getStrVal());

			}

		
		} finally {
			frameFix.cleanUp();
		}

	}

	/**
	 * Tests the setting of values, and deselection selection of rows from the
	 * cobean
	 */
	@Test
	public void testSelectDeselectFromCobean() {
		TableNotificationTestFrame frame = new TableNotificationTestFrame("TF");
		FrameFixture frameFix = new FrameFixture(frame);
		try {
			frameFix.show();
			JTableFixture tableFix = frameFix.table("table");

			// Create to property change listeners for recording the events.
			final RecordingPropertyChangeListener valueListener = new RecordingPropertyChangeListener(
					"value");
			final RecordingPropertyChangeListener selListener = new RecordingPropertyChangeListener(
					"selectedValue");

			// Create the cobean
			ISingleSelectionListCobean<SimpleBean> cobean = createCobean(frame);

			// Add the listeners to the cobean
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(valueListener);
			((IPropertyChangeListenerAware) cobean)
					.setPropertyChangeListener(selListener);

			// Set a list of Simple beans to the cobean
			List<SimpleBean> value = CobeanTestUtil
					.createSimpleBeanList("Der Assistent der Zauberer");
			{
				cobean.setValue(value);
				// Assert that the value listener was notified exactly ones
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(0, selListener.getNotificationCount());
				assertEventContentBean(null, CobeanTestUtil
						.createSimpleBeanList("Der Assistent der Zauberer"),
						"value", valueListener.getEventContents().get(0));
			}

			// Select one row from the cobean
			{
				cobean.setSelectedValue(value.get(3));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(1, selListener.getNotificationCount());
				assertEventContentBean(null, new SimpleBean("Zauberer"),
						"selectedValue", selListener.getEventContents().get(0));
			}

			// Select another row from the cobean
			{
				cobean.setSelectedValue(value.get(2));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Zauberer"),
						new SimpleBean("der"), "selectedValue", selListener
								.getEventContents().get(1));
			}

			// Select the same row from the cobean
			{
				cobean.setSelectedValue(value.get(2));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(2, selListener.getNotificationCount());
			}

			// Select another row from the cobean
			{
				cobean.setSelectedValue(value.get(1));
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(3, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("der"), new SimpleBean(
						"Assistent"), "selectedValue", selListener
						.getEventContents().get(2));
			}
			// Deselect from the cobean
			{
				cobean.setSelectedValue(null);
				pause();
				assertEquals(1, valueListener.getNotificationCount());
				assertEquals(4, selListener.getNotificationCount());
				assertEventContentBean(new SimpleBean("Assistent"), null,
						"selectedValue", selListener.getEventContents().get(3));
				tableFix.requireNoSelection();
			}

		} finally {
			frameFix.cleanUp();
		}

	}

	private <T> void assertEventContentBean(Object oldValue, Object newValue,
			String propertyName, EventContentBean eventContentBean) {
		assertEquals(oldValue, eventContentBean.getOldValue());
		assertEquals(newValue, eventContentBean.getNewValue());
		assertEquals(propertyName, eventContentBean.getPropertyName());

	}

	private synchronized void pause() {
		try {
			this.wait(100);
		} catch (InterruptedException e) {
			// Can be ignored
		}
	}

	@SuppressWarnings("unused")
	private synchronized void pauseLong() {
		try {
			this.wait(3000);
		} catch (InterruptedException e) {
			// Can be ignored
		}
	}

	private ISingleSelectionListCobean<SimpleBean> createCobean(
			TableNotificationTestFrame frame) {
		final DefaultSingleSelectionTableInitializer<SimpleBean> ini = new DefaultSingleSelectionTableInitializer<SimpleBean>();
		ini.setColumnDescs(ColumnDesc
				.createFilterableSortableColumnDescs("strVal"));
		ini.setCoTable(frame.getTable());
		ini.setCoFilterInput(frame.getFilterTextField());
		ISingleSelectionListCobean<SimpleBean> cobean = ini.initialize();
		return cobean;
	}

}
